import { ECS } from "./ECS";
import { SystemClass } from "./System";

const _systemClassMap:Map<string, SystemClass[]> = new Map();

/**
 * 注册系统
 * @param ecsName 系统所属的ECS名称
 * @returns 
 */
export function system(ecsName:string="default"): any {
    return function (target:SystemClass, propertyKey: string) {
        let classArr:SystemClass[] = _systemClassMap.get(ecsName);
        if(!classArr) {
            classArr = [];
            _systemClassMap.set(ecsName, classArr)
        }
        classArr.push(target);
        _systemClassMap.set(ecsName, classArr);
    }
}

function getSystemClassesOfECS(ecsName:string):SystemClass[] {
    let result = _systemClassMap.get(ecsName);
    return result;
}

class ECSManager {
    private _ecss:Map<string, ECS>;
    private static created:boolean = false;
    constructor(){
        if(ECSManager.created){
            throw new Error("ECSManager is singleton!");
        }
        ECSManager.created = true;
        this._ecss = new Map();
    }

    /**
     * 现存的ECS数量
     */
    get count():number {
        return this._ecss.size;
    }

    /**
     * 是否存在ECS
     * @param name ECS名称 
     * @returns 
     */
    has(name:string):boolean {
        return this._ecss.has(name);
    }

    /**
     * 获取ECS
     * @param name 
     * @returns 
     */
    get(name:string):ECS|undefined {
        return this._ecss.get(name);
    }

    /**
     * 获取现存的ECS
     * @returns 
     */
    getAll():ECS[] {
        return Array.from(this._ecss.values())
    }

    /**
     * 创建ECS
     * @param name ECS名称,默认为default
     * @returns 
     */
    create(name:string="default"):ECS {
        if(this.has(name)){
            throw new Error(`Already exist ECS:${name}`);
        }
        let result:ECS = new ECS(name);
        this._ecss.set(name, result);
        let systemClassList = getSystemClassesOfECS(name);
        if(!systemClassList || systemClassList.length == 0){
            console.warn(`没有检测到属于ECS:${name}的System`);
        }else {
            result.addSystem(...systemClassList);
        }
        return result;
    }

    /**
     * 释放ECS
     * @param ecs ECS对象
     */
    release(ecs:ECS):boolean;
    /**
     * 销毁ECS
     * @param name ECS名称
     */
    release(name:string):boolean;
    release(target:string|ECS):boolean {
        if(typeof target === "string"){
            return this._releaseByName(target);
        } else if(target instanceof ECS){
            return this._release(target);
        }
        return false;
    }

    private _releaseByName(name:string):boolean {
        let ecs = this.get(name);
        if(ecs){
            return this._release(ecs);
        }
        return false;
    }

    private _release(target:ECS):boolean {
        target.reset();
        return this._ecss.delete(target.name);
    }
}

/**
 * ECS管理器
 */
export var manager:ECSManager = new ECSManager();